﻿Option Explicit On
Public Class main
    '读取inf文件相关的声明
    Public Declare Function GetPrivateProfileStringKey Lib "kernel32" Alias "GetPrivateProfileStringA" (ByVal lpApplicationName As String, ByVal lpKeyName As String, ByVal lpDefault As String, ByVal lpReturnedString As String, ByVal nSize As Integer, ByVal lpFileName As String) As Integer
    '和进程相关的声明，主要是执行外部程序，并且在其退出时获得退出代码
    Dim WithEvents p As Diagnostics.Process
    '和文件下载相关的声明，有下载进度条
    Dim wc As System.Net.WebClient
    '其他变量的声明
    Dim Checking, Downloading As Boolean
    Dim lastest_date, current_date As Integer
    Dim path, apploca As String

    Private Sub OnFileDownloadCompleted(ByVal sender As Object, ByVal e As System.ComponentModel.AsyncCompletedEventArgs)
        On Error GoTo ExEr
        If e.Cancelled Then
            '下载取消
            MsgBox("下载取消！", MsgBoxStyle.Information, "提示")
        ElseIf Not e.Error Is Nothing Then
            '下载出错
            MsgBox("下载失败！", MsgBoxStyle.Exclamation, "提示")
        Else
            '下载成功
            If Checking = True Then
                '读取inf文件info下各项的值，并赋予给txt_lastestversion.Text，lastest_date等
                Dim lpDefault$, lpReturnString$, lpFileName$
                Dim Size%, Valid%
                Dim text
                lpDefault$ = "0000"
                lpReturnString$ = Space$(128)
                Size% = Len(lpReturnString$)
                lpFileName$ = apploca & "\version.inf"
                Valid% = GetPrivateProfileStringKey("info", "version", lpDefault$, lpReturnString$, Size%, lpFileName$)
                text = Microsoft.VisualBasic.Left(lpReturnString$, Valid%)
                If text = "0000" Then
                    GoTo VerinfoEr
                End If
                txt_lastestversion.Visible = True
                lastestversion.Visible = True
                txt_lastestversion.Text = text
                Valid% = GetPrivateProfileStringKey("info", "date", lpDefault$, lpReturnString$, Size%, lpFileName$)
                lastest_date = Microsoft.VisualBasic.Left(lpReturnString$, Valid%)
                If lastest_date = "0000" Then
                    GoTo VerinfoEr
                End If
                '检查version.inf文件中的版本信息是否大于当前aplication.inf中的信息
                If lastest_date > current_date Then
                    updatenow.Enabled = True
                    Valid% = GetPrivateProfileStringKey("info", "details", lpDefault$, lpReturnString$, Size%, lpFileName$)
                    text = Microsoft.VisualBasic.Left(lpReturnString$, Valid%)
                    txt_detail.Text = text
                Else
                    txt_detail.Text = "当前已经是最新版本！"
                    Kill(apploca & "\version.inf")
                End If
            Else
                MsgBox("下载成功！即将安装更新！", MsgBoxStyle.Information, "提示")
                '释放资源中的7zip解压缩程序
                Dim bFile() As Byte
                bFile = (My.Resources._7za)
                FileOpen(1, "7za.exe", OpenMode.Binary)
                FilePut(1, bFile)
                FileClose(1)
                '执行7za.exe
                p = New Diagnostics.Process()
                AddHandler p.Exited, AddressOf p_Exited
                p.EnableRaisingEvents = True
                p.SynchronizingObject = Me
                p.StartInfo.FileName = apploca & "\7za.exe"
                p.StartInfo.Arguments = "x -aoa " & path
                p.Start()
            End If
        End If
        Downloading = False
        Exit Sub
ExEr:
        MsgBox("程序出错！", MsgBoxStyle.Information, "错误！")
        Exit Sub
VerinfoEr:
        MsgBox("更新信息损坏！", MsgBoxStyle.Information, "错误！")
    End Sub

    Private Sub p_Exited(ByVal sender As Object, ByVal e As System.EventArgs)
        '7zip退出时，获取7zip的退出代码，0则为操作成功
        If p.ExitCode = 0 Then
            MessageBox.Show("解压完毕！")
            Kill(path)
            Kill(apploca & "\7za.exe")
            Me.Hide()
            Waiting.ShowDialog()
        Else
            MessageBox.Show("解压过程出现错误！请重试！")
            Kill(path)
            Kill(apploca & "\7za.exe")
        End If
    End Sub

    Private Sub OnDownloadProgressChanged(ByVal sender As Object, ByVal e As System.Net.DownloadProgressChangedEventArgs)
        '下载进度发生改变时的执行
        Dim totalSize As Long = e.TotalBytesToReceive
        Dim downloadedBytes As Long = e.BytesReceived
        Dim percentage As Integer = e.ProgressPercentage
        '你可以添加自己的下载UI界面，如果需要取消下载，就用下面的一行
        'wc.CancelAsync()
        ProgressBar1.Value = percentage
        dlinfo.Text = "已接收：" & downloadedBytes & "字节。总共：" & totalSize & "字节。已完成：" & percentage & "%"
    End Sub

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        On Error GoTo LoadError
        Dim lpDefault$, lpReturnString$, lpFileName$
        Dim Size%, Valid%
        Dim text
        apploca = My.Application.Info.DirectoryPath
        updatenow.Enabled = False
        Downloading = False
        '获取aplication.inf里面的相关信息，如果值不存在，或者错误，则返回"0000"
        lpDefault$ = "0000"
        lpReturnString$ = Space$(128)
        Size% = Len(lpReturnString$)
        lpFileName$ = apploca & "\aplication.inf"
        Valid% = GetPrivateProfileStringKey("info", "name", lpDefault$, lpReturnString$, Size%, lpFileName$)
        text = Microsoft.VisualBasic.Left(lpReturnString$, Valid%)
        txt_appname.Text = text
        Valid% = GetPrivateProfileStringKey("info", "version", lpDefault$, lpReturnString$, Size%, lpFileName$)
        text = Microsoft.VisualBasic.Left(lpReturnString$, Valid%)
        txt_currentversion.Text = text
        Valid% = GetPrivateProfileStringKey("info", "date", lpDefault$, lpReturnString$, Size%, lpFileName$)
        current_date = Microsoft.VisualBasic.Left(lpReturnString$, Valid%)
        If txt_appname.Text = "0000" Then
            GoTo LoadError
        End If
        Exit Sub
LoadError:
        MsgBox("程序信息缺失!", MsgBoxStyle.Critical, "错误!")

    End Sub

    Private Sub Check_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Check.Click
        On Error GoTo CheckError
        Checking = True
        Downloading = True
        '启动下载，下载保存在程序设置里CheckUrl值的url所指向的文件
        wc = New System.Net.WebClient()
        AddHandler wc.DownloadProgressChanged, AddressOf OnDownloadProgressChanged
        AddHandler wc.DownloadFileCompleted, AddressOf OnFileDownloadCompleted
        wc.DownloadFileAsync(New Uri(My.Settings.CheckUrl), apploca & "\version.inf")
        dlinfo.Text = "连接中..."
        Exit Sub
CheckError:
        MsgBox("Check Error!", MsgBoxStyle.Critical, "错误!")
    End Sub

    Private Sub updatenow_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles updatenow.Click
        On Error GoTo UrlError
        Checking = False
        Downloading = True
        Dim lpDefault$, lpReturnString$, lpFileName$
        Dim Size%, Valid%
        Dim url, filename
        '获取version.inf所包含的下载信息，并开始下载文件
        lpDefault$ = "0000"
        lpReturnString$ = Space$(128)
        Size% = Len(lpReturnString$)
        lpFileName$ = apploca & "\version.inf"
        Valid% = GetPrivateProfileStringKey("info", "url", lpDefault$, lpReturnString$, Size%, lpFileName$)
        url = Microsoft.VisualBasic.Left(lpReturnString$, Valid%)
        filename = Microsoft.VisualBasic.Right(url, Len(url) - InStrRev(url, "/"))
        path = apploca & "\" & filename
        wc = New System.Net.WebClient()
        AddHandler wc.DownloadProgressChanged, AddressOf OnDownloadProgressChanged
        AddHandler wc.DownloadFileCompleted, AddressOf OnFileDownloadCompleted
        wc.DownloadFileAsync(New Uri(My.Settings.CheckUrl), path)
        dlinfo.Text = "连接中..."
        Exit Sub
UrlError:
        MsgBox("URL Error!", MsgBoxStyle.Critical, "错误!")
    End Sub

    Private Sub cancel_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cancel.Click
        If Downloading = False Then
            End
        End If
        wc.CancelAsync()
    End Sub
End Class